package com.task.controller.param.impl;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.task.controller.annotation.Param;
import com.task.controller.param.ParamParser;
import ohos.app.Context;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class ToObjectParser implements ParamParser {

    private Gson gson;

    @Override
    public Object parse(Context context, Object s, Method method) {
        if (gson == null) {
            gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();
        }
        Parameter[] parameters = method.getParameters();
        try {
            return getParam(context, s, parameters);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return null;
    }

    private List<Object> getParam(Context context, Object fromJson, Parameter[] parameters) throws IllegalAccessException {
        Class<?> aClass = fromJson.getClass();
        List<Field> list = new ArrayList<>(Arrays.asList(aClass.getDeclaredFields()));
        searchField(aClass, list);
        List<Object> params = new ArrayList<>();
        for (Parameter parameter : parameters) {
            if (parameter.getType().isInstance(context)) {
                params.add(context);
                continue;
            }
            String name;
            Param param = parameter.getDeclaredAnnotation(Param.class);
            if (param != null) {
                name = param.name();
            } else {
                name = parameter.getName();
            }
            for (Field field : list) {
                String fieldName = field.getName();
                if (fieldName.endsWith(name)) {
                    field.setAccessible(true);
                    Object o = field.get(fromJson);
                    params.add(o);
                    break;
                }
            }
        }
        return params;
    }

    private void searchField(Class<?> aClass, List<Field> list) {
        Class<?> cls = aClass;
        while (!(cls = cls.getSuperclass()).equals(Object.class)) {
            list.addAll(new ArrayList<>(Arrays.asList(cls.getDeclaredFields())));
        }
    }
}
